package com.demo.resourcecode.c11mvc;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**是用来全局定制化springboot的mvc特性，开发者通过实现WebMvcConfigurer接口来配置应用的mvc全局特性
 * @author DELL
 *
 */
@Configuration
public class MvcConfigurer extends WebMvcConfigurerAdapter {

	public MvcConfigurer(){
		System.out.println("init MvcConfigurer");
	}

	//拦截器
	@Override
	public void addInterceptors(InterceptorRegistry registry){
		// 增加一个拦截器，检查会话，url以admin开头的都使用此拦截器
		registry.addInterceptor(new MyTestInterceptor());
		// addInterceptor方法返回的InterceptorRegistration提供的方法可以对该拦截器进行配置，包括以下方法
		//registry.addInterceptor(new MyTestInterceptor())
				//.addPathPatterns("") // 添加此拦截器拦截的路径模式
				//.excludePathPatterns("") // 添加此拦截排除的路径模式，不拦截符合模式的请求
				//.order(1); // 配置此拦截器的拦截顺序
	}

	@Bean
	public ViewResolver internalResourceViewResolver(){
		InternalResourceViewResolver view = new InternalResourceViewResolver();
		view.setPrefix("/WEB-INF/views/");
		view.setSuffix(".jsp");
		return view;
	}

	@Override
	public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
		configurer.setDefaultTimeout(3000); // 配置默认异步请求超时时间，默认10s
		// configurer.setTaskExecutor(AsyncTaskExecutor); // 配置异步任务的执行器，默认使用SimpleAsyncTaskExecutor
		// configurer.registerCallableInterceptors(CallableProcessingInterceptor... interceptors); // 注册异步请求的Callable拦截器
		// configurer.registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors); // 注册异步请求的DeferredResult拦截器
	}

	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {
		configurer.setUseSuffixPatternMatch(false); // 配置是否启用后缀匹配模式，启用时对于路径模式可额外匹配带有扩展名的请求路径，如请求/user.json也可以匹配到/user路径下的请求处理器，默认为false
		configurer.setUseTrailingSlashMatch(true); // 配置是否对请求路径中以"/"结尾的请求在匹配不到请求处理器时，自动为路径模式结尾添加"/"后再进行路径匹配。如对localhost:8080/user/的请求，使用/user路径对应的请求处理器处理该请求，默认为true
		configurer.setUseRegisteredSuffixPatternMatch(false); // 对于后缀匹配模式，是否只匹配已知的文件扩展名后缀，默认为false
		//configurer.setPathMatcher(PathMatcher); // 设置路径匹配器，默认为AntPathMatcher
		//configurer.setUrlPathHelper(UrlPathHelper); // 设置url路径工具类，默认为UrlPathHelper
	}

	@Override
	public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
		//configurer.mediaType(extension, mediaType);
		//configurer.favorParameter(false); // 对于响应接收的ContentType类型，是否优先从请求参数中获取，请求参数名默认是format。该配置默认为false
		//configurer.parameterName(parameterName); // 设置请求参数中ContentType的参数名，对应favorParameter配置，默认为format
		configurer.favorPathExtension(false); // 是否优先使用请求的路径扩展名来判断响应的ContentType，如请求路径以.pdf结尾，则优先视为返回application/pdf类型的响应，默认为false
	}

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		//registry.viewResolver(viewResolver); // 添加视图解析器
		//registry.beanName(); // 添加beanNameViewResolver
		//registry.freeMarker(); // 添加FreeMarker视图解析器，并返回UrlBasedViewResolverRegistration注册器，可以为FreeMarker视图解析器进行配置。可配置项包括视图查找的前缀、后缀、是否为视图添加缓存等。使用该方法的前提是对应的FreeMarker依赖存在
		// 其他模板，例如jsp、tiles、groovy等，功能同上
	}

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		// 添加重定向视图控制器，对于/路径的请求，重定向到/user下
		registry.addRedirectViewController("/", "/user");
		registry.addRedirectViewController("/aa/*", "/user");
		// 添加视图控制器，对于/user/**模式的请求，直接使用视图/assets/index.html进行相应
		registry.addViewController("/user/**").setViewName("/assets/index.html");
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		// 添加静态资源处理器，对于/static/**路径模式的请求，在classpath下的assets文件夹中查找对应的静态资源并返回，在浏览器缓存24小时
		registry.addResourceHandler("/static/**")
			.addResourceLocations("classpath:/assets/")
			.setCachePeriod(24 * 60 * 60);
	}

}
